﻿// A tooltip is an overlay that shows around a target when some action happens on the target
define([
    'Wjs/ui/widgets/foundation/Overlay'
],
function () {
    'use strict';

    var updatePosition;

    return Wjs.defineOnce({

        type: 'Tooltip',

        internal: {

            base: Wjs.getType('Overlay'),

            onBeforeTypeDefined: function () {
                var body = Wjs.getType('body');

                updatePosition = function (target, tooltip, placement) {
                    var targetRect = target.getRectangle(),
                        tooltipRect = tooltip.getRectangle(),
                        tooltipWidth = tooltipRect.width ? tooltipRect.width : (tooltipRect.right - tooltipRect.left),
                        tooltipHeight = tooltipRect.height ? tooltipRect.height : (tooltipRect.bottom - tooltipRect.top),
                        viewportWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, // body.getViewportWidth(),
                        viewportHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; // body.getViewportHeight();

                    switch (placement) {

                        case 'rightside-left': // Placed left from the right side of the target
                            {
                                if (tooltipWidth <= targetRect.right) { // There is enough room on the left side

                                    tooltip.setLeft(targetRect.right - tooltipWidth);
                                }
                                else { // Slide to the right

                                    tooltip.setLeft(tooltipWidth - targetRect.right);
                                }
                            }
                            break;

                        case 'bottomside-bottom':
                            {
                                if (tooltipHeight <= viewportHeight - targetRect.bottom) { // There is enough room on the bottom area

                                    tooltip.setTop(targetRect.bottom);
                                }
                                else if (tooltipHeight <= targetRect.top) { // Not slideable, move to top

                                    tooltip.setTop(targetRect.top - tooltipHeight);
                                }
                                else { // No room at either side. Set it at the bottom anyway

                                    tooltip.setTop(targetRect.bottom);
                                }

                            }
                            break;

                        default: throw 'Unknown placement: ' + placement;
                    }
                }
            },

            initialize: function (cfg, parent) {
                var me = this;

                me.setUseVisibility(); // Set it to use visibility so the hiden element is measurable and can be manipulated in the onBeforeShow handler

                me.action = 'hover';
                me.placements = ['rightside-left', 'bottomside-bottom'];

                me.onRender(function () {

                    me.setAction(me.action);
                });

                me.onBeforeShow(function () { // setUseVisibility is set so the element is measurable when hidden

                    me.placements.forEach(function (placement) {

                        updatePosition(me.target, me, placement);
                    });

                });

            }
        },

        setTarget: function (target) {

            this.target = target;

            return this;
        },

        setPlacements: function (placements) {

            if (Wjs.isString(placements)) {

                placements = placements.toLowercase().split(' ');
            }

            placements.forEach(function (placement, i) {

                placements[i] = placement.trim();
            });

            this.placements = placements;

            return this;
        },

        setAction: function (action) {
            var me = this;

            me.action = action;

            if (me.isRendered()) { // Add the events to the target only if the tooltip has been rendered

                switch (me.action) {

                    case 'hover':
                        {
                            me.target.addEvents({

                                'mouseover': function (evt) {

                                    me.show();
                                },

                                'mouseout': function () {

                                    me.hide();
                                }
                            });
                        }
                        break;

                    case 'click':
                        {
                            me.target.addEvents({

                                'click': function (evt) {

                                    me.show();
                                }
                            });

                            //me.addEvents({ // Hide the tooltip on mouse out

                            //    'mouseout': function (evt) {

                            //        me.hide();
                            //    }
                            //});
                        }
                        break;

                    default: throw 'Unknown tooltip action: ' + me.action;
                }

            }

            return me;
        }

    });
});
